#include <utils/stack_emulator.h>

void stackemu_construct(stackemu_context_t *ctx, uint64_t stack_top) {
	ctx->sp = stack_top;
	ctx->bp = stack_top;
}

void stackemu_push(stackemu_context_t *ctx, uint64_t value) {
	ctx->sp -= sizeof(uint64_t);
	*(uint64_t *)ctx->sp = value;
}

uint64_t stackemu_pop(stackemu_context_t *ctx) {
	uint64_t value = *(uint64_t *)ctx->sp;
	ctx->sp += sizeof(uint64_t);
	return value;
}

void stackemu_storebp(stackemu_context_t *ctx) {
	stackemu_push(ctx, ctx->bp);
	ctx->bp = ctx->sp;
}

void stackemu_restorebp(stackemu_context_t *ctx) {
	ctx->bp = stackemu_pop(ctx);
}

void *stackemu_alloc(stackemu_context_t *ctx, uint64_t size) {
	ctx->bp -= (size + 7) & ~7;

	return (void *)ctx->bp;
}